package ign.agents;

import ign.Performatives;
import ign.behaviours.building.BuildingListening;
import ign.behaviours.building.ResetState;
import jade.core.AID;
import jade.core.Agent;
import jade.domain.DFService;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.domain.FIPAException;
import jade.lang.acl.ACLMessage;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Cette classe est un agent Batiment.
 * @author Simon Bourigaut & Ghislain Di Paolo
 */
public class Building extends Agent {
	private static final long serialVersionUID = -8020387047045792541L;
	
	/* Les positions courantes de l'agent */
	private int x, y, width, height;
	/* Les positions originelles de l'agent */
	private int orig_x, orig_y;
	/* L'adresse de l'ihm */
	private DFAgentDescription ihm_ad;
	/* Le numéro de l'ihm */
	private AID ihm_aid;
	/* L'état de la propagation */
	private int moves = 0 ;
	
	/**
	 * Constructeur prenant une position en paramètre, qui sera assignée
	 * à sa position originelle.
	 * @param x	l'abscisse
	 * @param y	l'ordonnée
	 * @param width	la largeur
	 * @param height la hauteur.
	 */
	public Building(int x, int y, int width, int height) {
		super();
		
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		
		orig_x = (x + width) / 2;
		orig_y = (y + height) / 2;
	}
	
	/**
	 * Renvoi la position originelle du batiment en abscisse.
	 * @return 
	 */
	public int getOrigX(){
		return orig_x;
	}
	
	/**
	 * Renvoie la position originelle du batiment en ordonnée.
	 * @return 
	 */
	public int getOrigY(){
		return orig_y;
	}
	
	@Override
	protected void setup(){

		DFAgentDescription d = new DFAgentDescription();
		d.setName(getAID());
		
		ServiceDescription sd = new ServiceDescription();
		sd.setType("Building");
		sd.setName("building1");
		d.addServices(sd);

		try {
			DFService.register(this, d);
		} catch (FIPAException e) {
			Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, e);
		}
		
		/* Envoie un message a l'IHM */
		ServiceDescription ihm_sd = new ServiceDescription();
		ihm_sd.setType("IHM");
		
		ihm_ad = new DFAgentDescription();
		ihm_ad.addServices(ihm_sd);
		DFAgentDescription[] res;
		try {
			
			res = DFService.search(this, ihm_ad);
			
		} catch (FIPAException e) {
			Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, e);
			return;
		}
		
		/* Make the message */
		ACLMessage mess = new ACLMessage(Performatives.NEW_BUILDING);
		mess.setContent("" + x + ";" + y + ";" + width + ";" + height);
		this.ihm_aid = res[0].getName();
		mess.addReceiver(ihm_aid);
		send(mess);
		
		/* Ajout des behaviour */
		addBehaviour(new BuildingListening());
		addBehaviour(new ResetState(this, 2000));
	}
	

	/**
	 * Renvoie le numéro de l'ihm.
	 * @return le numéro unique de l'ihm
	 */
	public AID getIhm_aid() {
		return ihm_aid;
	}
	
	@Override
	protected void takeDown(){
		/* Dire à l'IHM que l'agent disparait */
		ACLMessage mess = new ACLMessage(Performatives.GOODBYE_WORLD);
		mess.addReceiver(ihm_aid);
		send(mess);
	}

	/**
	 * Renvoi l'abscisse du batiment.
	 * @return 
	 */
	public int getX() {
		return x;
	}

	/**
	 * Renvoi l'ordonnée du batiment.
	 * @return 
	 */
	public int getY() {
		return y;
	}

	/**
	 * Renvoi la largeur du batiment.
	 * @return 
	 */
	public int getWidth() {
		return width;
	}

	/**
	 * Renvoi la hauteur du batiment.
	 * @return 
	 */
	public int getHeight() {
		return height;
	}

	/**
	 * Renvoi l'adresse de l'agent ihm dans les pages jaunes.
	 * @return 
	 */
	public DFAgentDescription getIhm_ad() {
		return ihm_ad;
	}
	
	/**
	 * Déplace le batiment d'un certain nombre de pixels.
	 * @param delta_x le d"placement en abscisse.
	 * @param delta_y le déplacement en ordonné.
	 */
	public void move(int delta_x, int delta_y){
		this.x += delta_x;
		this.y += delta_y;
		
		ACLMessage mess = new ACLMessage(Performatives.NEW_POSITION);
		mess.setContent("" + x + ";" + y + ";" + width + ";" + height);
		mess.addReceiver(ihm_aid);
		send(mess);
				
	}
	
	/**
	 * Renvoi l'état de la propagation.
	 * @return 
	 */
	public int getPropState() {
		return moves;
	}
	
	/**
	 * Set l'etat de la propagation.
	 * @param i la valeur
	 */
	public void setPropState(int i) {
		
		if (i < 0)
			i = 0;
		
		moves = i;
	}
	
	/**
	 * Remet à 0 l'état de la propagation.
	 */
	public void resetProp(){
		
		setPropState(0);
	}
}
